﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Vortex.Drawing {

	/// <summary>
	/// Blending contains instruction how to blend source (computed) pixel value and destination pixel value
	/// </summary>
	public class Blending {		
		private BlendFactor _sourceFactor;
		private BlendFactor _destFactor;
		private BlendOperation _operation;

		/// <summary>
		/// Initializes a new instance of the <see cref="Blending"/> class.
		/// </summary>
		/// <param name="sourceFactor">The source factor.</param>
		/// <param name="destFactor">The destination factor.</param>
		/// <param name="operation">The operation.</param>
		public Blending(BlendFactor sourceFactor, BlendFactor destFactor, BlendOperation operation) {
			_sourceFactor = sourceFactor;
			_destFactor = destFactor;
			_operation = operation;
		}

		/// <summary>
		/// Gets the source factor for blending.
		/// </summary>
		/// <value>The source factor.</value>
		public BlendFactor SourceFactor {
			get { return _sourceFactor; }
		}

		/// <summary>
		/// Gets the destination factor.
		/// </summary>
		/// <value>The destination factor.</value>
		public BlendFactor DestFactor {
			get { return _destFactor; }
		}

		/// <summary>
		/// Gets the blending operation.
		/// </summary>
		/// <value>The blending operation.</value>
		public BlendOperation Operation {
			get { return _operation; }
		}

		///<summary>Disables blending, source pixel value overrides destination fully</summary>
		public readonly static Blending None = new Blending(BlendFactor.One, BlendFactor.Zero, BlendOperation.Add);
		///<summary>Source pixel value is added to existing one</summary>
		public readonly static Blending Add = new Blending(BlendFactor.SrcAlpha, BlendFactor.One, BlendOperation.Add);
		/// <summary>Normal blending, source value multiplied on alpha is added to destination pixel value multiplied on (1 - alpha)</summary>
		public readonly static Blending Normal = new Blending(BlendFactor.SrcAlpha, BlendFactor.InvSrcAlpha, BlendOperation.Add);
		///<summary>Source pixel value is subtracted from destination value</summary>
		public readonly static Blending Subtract = new Blending(BlendFactor.SrcAlpha, BlendFactor.One, BlendOperation.RevSubtract);

		#region Blending Comparison

		/// <summary>
		/// Compares the specified blending with other.
		/// </summary>
		/// <param name="other">The other blending to compare with this instance.</param>
		/// <returns>
		///		<c>true</c> if the specified <see cref="Blending"/> is equal to this instance; otherwise, <c>false</c>.
		/// </returns>
		public bool Equals(Blending other) {
			if (null != other) {
				return _sourceFactor == other._sourceFactor && _destFactor == other._destFactor && _operation == other._operation;
			} else {
				return false;
			}
		}

		/// <summary>
		/// Compares two blendings with other.
		/// </summary>
		/// <param name="left">The left.</param>
		/// <param name="right">The right.</param>
		/// <returns>
		///		<c>true</c> if the both <see cref="Blending"/> instances are equal; otherwise, <c>false</c>.
		///	</returns>
		public static bool Equals(Blending left, Blending right) {
			if (null != left) {
				return left.Equals(right);
			} else {
				return left == right;
			}
		}

		#endregion
	}
}
